package com.area42games.grammar;

import static org.junit.Assert.*;

import java.util.List;
import org.junit.Test;

import com.area42games.grammar.trees.EvalContext;

public class DiceParserTest 
{
//	@Test
//	public void testRegex()
//	{
//		String input = "Roll(1d6)";
//		List<String> list = DiceParser.findStatements(DiceParser.rollP, input);
//		List<String> list2 = DiceParser.findStatements(DiceParser.refP, input);
//		List<String> list3 = DiceParser.findStatements(DiceParser.setP, input);
//		assertEquals(1,list.size());
//		String item = list.get(0);
//		assertEquals(true,item != null);
//		assertEquals(true,item.equals("1d6"));
//		
//		input = "Roll(1d6) Roll(2d6) Ref(hello world) Set(bob=your uncle)";
//		String input2 = input;
//		String input3 = input;
//		list = DiceParser.findStatements(DiceParser.rollP, input);
//		list2 = DiceParser.findStatements(DiceParser.refP, input2);
//		list3 = DiceParser.findStatements(DiceParser.setP, input3);
//		assertEquals(2,list.size());
//		assertEquals(1,list2.size());
//		assertEquals(1,list3.size());
//		item = list.get(0);
//		assertEquals(true,item != null);
//		assertEquals(true,item.equals("1d6"));
//
//		item = list.get(1);
//		assertEquals(true,item != null);
//		assertEquals(true,item.equals("2d6"));
//
//		item = list2.get(0);
//		assertEquals(true,item != null);
//		assertEquals(true,item.equals("hello world"));
//
//		item = list3.get(0);
//		assertEquals(true,item != null);
//		assertEquals(true,item.equals("bob=your uncle"));
//	}
	
	@Test
	public void testSingleNumber() 
	{
		assertEquals(1, DiceParserDriver.eval("1"));
		assertEquals(2, DiceParserDriver.eval("2"));
		assertEquals(3, DiceParserDriver.eval("3"));
		assertEquals(4, DiceParserDriver.eval("4"));
		assertEquals(5, DiceParserDriver.eval("5"));
		assertEquals(6, DiceParserDriver.eval("6"));
		assertEquals(7, DiceParserDriver.eval("7"));
		assertEquals(8, DiceParserDriver.eval("8"));
		assertEquals(9, DiceParserDriver.eval("9"));
	}

	@Test
	public void testMultipleNumber() 
	{
		assertEquals(10, DiceParserDriver.eval("10"));
		assertEquals(21, DiceParserDriver.eval("21"));
		assertEquals(321, DiceParserDriver.eval("321"));
		assertEquals(4321, DiceParserDriver.eval("4321"));
		assertEquals(54321, DiceParserDriver.eval("54321"));
		assertEquals(654321, DiceParserDriver.eval("654321"));
		assertEquals(7654321, DiceParserDriver.eval("7654321"));
		assertEquals(87654321, DiceParserDriver.eval("87654321"));
		assertEquals(2147483647, DiceParserDriver.eval("2147483647"));
	}

	@Test
	public void testAddition() 
	{
//		assertEquals(1, NewDiceParser.eval("1+"));
		assertEquals(1, DiceParserDriver.eval("+1"));
		assertEquals(10, DiceParserDriver.eval("1+9"));
		assertEquals(100, DiceParserDriver.eval("1+9+90"));
	}

	@Test
	public void testSubtraction() 
	{
		assertEquals(-9, DiceParserDriver.eval("-9"));
//		assertEquals(9, NewDiceParser.eval("9-"));
		assertEquals(-8, DiceParserDriver.eval("1-9"));
		assertEquals(-98, DiceParserDriver.eval("1-9-90"));
	}

	@Test
	public void testMultiplicationAndDivision() 
	{
//		assertEquals(2, NewDiceParser.eval("2*"));
		assertEquals(1, DiceParserDriver.eval("1*1"));
		assertEquals(1, DiceParserDriver.eval("1/1"));
		assertEquals(2, DiceParserDriver.eval("2/1"));
		assertEquals(15, DiceParserDriver.eval("10/2*3"));
	}

	@Test
	public void testParenthesis() 
	{
		assertEquals(4, DiceParserDriver.eval("2*(1+1)"));
		assertEquals(10, DiceParserDriver.eval("60/(2*3)"));
		assertEquals(10, DiceParserDriver.eval("60/(2*(1+1+1))"));
	}

	@Test
	public void testRandom() 
	{
		int value = DiceParserDriver.eval("2d6");
		assertEquals(true, value >=2 );
		assertEquals(true, value <=12 );

		value = DiceParserDriver.eval("2d6+12");
		assertEquals(true, value >= 14 );
		assertEquals(true, value <= 26 );

		value = DiceParserDriver.eval("1d6*2");
		assertEquals(true, value >= 2 );
		assertEquals(true, value <= 12 );

		value = DiceParserDriver.eval("(3d4)");
		assertEquals(true, value >= 3 );
		assertEquals(true, value <= 12 );
	}

//	@Test
//	public void testMultipleExpressions()
//	{
//		String exp = NewDiceParser.explain("d20 [to hit]; 1d8+3 [damage]");
//		//System.out.println(exp);
//	}

//	@Test
//	public void testEachExpressions()
//	{
//		int value = NewDiceParser.eval("3@1");
//		assertEquals(true,3 == value);
//
//		String exp = NewDiceParser.explain("3@1d6+1");
//		//System.out.println(exp);
//	}

//	@Test 
//	public void testQualifiers()
//	{
//		int value = NewDiceParser.eval("1 [cold]");
//		assertEquals(true, value == 1 );
//
//		String exp = NewDiceParser.explain("1 [cold]");
//		assertEquals(true,exp.equals("1 [cold] => 1 [cold];\n"));
//	}

//	@Test 
//	public void testReferences()
//	{
//		List<QualifiedInteger> values = NewDiceParser.evalAll("1;$0");
//
//		assertEquals(values.get(0).getIntValue(),1);
//		assertEquals(values.get(1).getIntValue(),1);
//
//		List<String> explanations = NewDiceParser.explainAll("$0");
//
//		assertEquals(true,explanations.get(0).equals("Error: Referenced Value is NULL"));
//	}

	@Test
	public void testConditionals()
	{
		int value = DiceParserDriver.eval("2>1 ? (3>1?30:20) : 10");
		assertEquals(30,value);

		value = DiceParserDriver.eval("2>1 ? 3>1?30:20 : 10");
		assertEquals(value,30);
	}
		
}
